package com.cwn.wizbank.comm.utils;

import dm.jdbc.driver.DmDriver;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;



public class SecretUtil {
    // 数据库URL
    private static  String url = "jdbc:dm://172.15.75.53:5236/LMS";
    // 用户名
    private static  String user = "lms";
    // 密码
    private static  String password = "lms@@2024";
    // JDBC驱动类,达梦驱动
    private static  String classname = "dm.jdbc.driver.DmDriver";

    private static DmDriver dmDriver = null;

    /**
     * 此方法只做用户的解密和加密
     * @param args
     */
    public static void main(String[] args) {
        // 达梦数据库 -- 创建目标表
        //CREATE TABLE reguserCopy LIKE reguser;
        //-- 达梦数据库 使用DM DBMS的数据复制功能
        // INSERT INTO reguserCopy SELECT * FROM reguser;
        System.out.println("加密解密工具");
        doSecret(args);
    }

    private static void doSecret(String[] args) {
        String action = null;
        String tableName = null;
        String username = null;
        try {
            if (args.length == 2){
                action = args[0];
                tableName = args[1];
            } else if (args.length == 3){
                action = args[0];
                tableName = args[1];
                username = args[2];
            }else {
                System.out.println("参数错误:参数1 encrypt 加密");
                System.out.println("参数错误:参数1 decrypt 解密");
                System.out.println("参数错误:参数2 更新的用户表名");
                System.out.println("参数错误:参数3 更新用户的登陆名，不填为更新所有");
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!action.equals("encrypt") && !action.equals("decrypt")){
            return;
        }
        SecretUtil secretUtil = new SecretUtil();
        Connection connect = getConnect();
        if (connect!=null){
            List<User> userList = secretUtil.getSecret(connect, tableName, username);
            for (User user : userList) {
                if ("encrypt".equals(action)){
                    String encrypt_pwd = user.getUsr_pwd();
                    System.out.println("加密前：" + encrypt_pwd);
                    try {
                        encrypt_pwd = EncryptUtil.encrypt(encrypt_pwd, new StringBuffer(user.getUsr_ste_usr_id()).reverse().toString());
                        user.setUsr_pwd(encrypt_pwd);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println("加密后：" + encrypt_pwd);
                }else if ("decrypt".equals(action)){
                    String decrypt = user.getUsr_pwd();
                    System.out.println("解密前：" + decrypt);
                    try {
                        decrypt = EncryptUtil.decrypt(decrypt, new StringBuffer(user.getUsr_ste_usr_id()).reverse().toString());
                        user.setUsr_pwd(decrypt);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println("解密后：" + decrypt);
                }
            }
            setSecret(connect, tableName, userList);
        }
    }

    public static Connection getConnect() {
        try {
            // 加载Oracle JDBC驱动
            Class.forName(classname);
            // 建立数据库连接
            return DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<User> getSecret(Connection conn, String tableName, String username) {
        List<User> userList = new ArrayList<>();
        // 创建Statement对象
        Statement stmt = null;
        ResultSet rs = null;
        try {
            stmt = conn.createStatement();
            // 执行SQL查询
            String sql = "SELECT usr_ent_id,usr_ste_usr_id,usr_pwd FROM " + tableName;
            if (username != null && !username.equals("")){
                sql = "SELECT usr_ent_id,usr_ste_usr_id,usr_pwd FROM " + tableName + " where usr_ste_usr_id = '" + username +"'";
            }
            rs = stmt.executeQuery(sql);
            // 处理查询结果
            while (rs.next()) {
                User user = new User();
                user.setUsr_ent_id(rs.getString("usr_ent_id"));
                user.setUsr_ste_usr_id(rs.getString("usr_ste_usr_id"));
                user.setUsr_pwd(rs.getString("usr_pwd"));
                userList.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (rs != null){
                    rs.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return userList;
    }

    /**
     * 设置用户密码
     * @param conn 数据库连接
     * @param tableName 用户表名字
     * @param userList 用户列表
     */
    public static void setSecret(Connection conn, String tableName, List<User> userList) {
        if (userList == null || userList.size() == 0){
            return;
        }

        // 创建Statement对象
        PreparedStatement stmt = null;
        try {
            String sql = "update " + tableName + " set usr_pwd = ? where usr_ent_id = ? ";
            stmt = conn.prepareStatement(sql);
            for (User user : userList) {
                stmt.setString(1, user.getUsr_pwd());
                stmt.setString(2, user.getUsr_ent_id());
                // 执行SQL更新密码
                int count = stmt.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (stmt!=null){
                    stmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static final String KEY = "wethink202206280";
    private static final String ALGORITHMS = "AES/ECB/PKCS5Padding";

    public static String base64Encode(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }

    public static byte[] base64Decode(String base64Code) throws Exception {
        return new BASE64Decoder().decodeBuffer(base64Code);
    }

    public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(ALGORITHMS);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));

        return cipher.doFinal(content.getBytes("utf-8"));
    }

    public static String aesEncrypt(String content, String encryptKey) throws Exception {
        encryptKey = encryptKey == null || "".equals(encryptKey) ? KEY : encryptKey;
        return base64Encode(aesEncryptToBytes(content, encryptKey));
    }

    public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);

        Cipher cipher = Cipher.getInstance(ALGORITHMS);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
        byte[] decryptBytes = cipher.doFinal(encryptBytes);

        return new String(decryptBytes);
    }

    public static String aesDecryptCarryKey(String encryptStr, String decryptKey) throws Exception {
        return aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
    }

    public static String aesDecryptCarryKey(String encryptStr) throws Exception {
        String key = encryptStr.substring(0, 16);
        String pwd = encryptStr.substring(16);
        return aesDecryptByBytes(base64Decode(pwd), key);
    }

    public static String aesDecrypt(String encryptStr) throws Exception {
        return aesDecryptByBytes(base64Decode(encryptStr), KEY);
    }


    class User {
        private String usr_ent_id;
        private String usr_ste_usr_id;
        private String usr_pwd;

        public String getUsr_ent_id() {
            return usr_ent_id;
        }

        public void setUsr_ent_id(String usr_ent_id) {
            this.usr_ent_id = usr_ent_id;
        }

        public String getUsr_ste_usr_id() {
            return usr_ste_usr_id;
        }

        public void setUsr_ste_usr_id(String usr_ste_usr_id) {
            this.usr_ste_usr_id = usr_ste_usr_id;
        }

        public String getUsr_pwd() {
            return usr_pwd;
        }

        public void setUsr_pwd(String usr_pwd) {
            this.usr_pwd = usr_pwd;
        }
    }
}
